
package com.rt.schedulenew.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rt.schedulebase.dto.DictSerialDto;
import com.rt.schedulebase.entity.DictSerial;
import com.rt.schedulebase.mapper.DictSerialMapper;
import com.rt.schedulenew.api.IDictSerialService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class DictSerialServiceImpl extends ServiceImpl<DictSerialMapper, DictSerial> implements IDictSerialService {
    private Logger log = LoggerFactory.getLogger(DictSerialServiceImpl.class);
    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;

    @Override
    public boolean insertSelective(DictSerial dictSerial) {
        return retBool(baseMapper.insert(dictSerial));
    }

    @Override
    public boolean deleteByPrimaryKey(String key) {
        return retBool(baseMapper.deleteById(key));
    }

    @Override
    public boolean updateByPrimaryKeySelective(DictSerial dictSerial) {
        return retBool(baseMapper.updateById(dictSerial));
    }

    @Override
    public DictSerial selectByPrimaryKey(String key) {
        return baseMapper.selectById(key);
    }

    @Override
    public List<DictSerial> getList(DictSerialDto dto) {
        QueryWrapper<DictSerial> qw = new QueryWrapper<>();
        Map<String, Object> map = new HashMap<>();
        qw.allEq(map, false);
        List<DictSerial> list = baseMapper.selectList(qw);
        return list;
    }

    @Override
    public List<DictSerial> getListAll() {
        return baseMapper.selectList(null);
    }

    @Override
    public boolean delete(DictSerial dictSerial) {
        UpdateWrapper<DictSerial> uw = new UpdateWrapper<>();
        Map<String, Object> map = new HashMap<String, Object>();
        uw.allEq(map, false);
        return retBool(baseMapper.delete(uw));
    }

    @Override
    public boolean update(DictSerial dictSerial) {
        UpdateWrapper<DictSerial> uw = new UpdateWrapper<>();
        Map<String, Object> map = new HashMap<>();
        uw.allEq(map, false);
        return retBool(baseMapper.update(dictSerial, uw));
    }

    @Override
    public DictSerial getInfo(DictSerialDto dto) {
        QueryWrapper<DictSerial> qw = new QueryWrapper<>();
        Map<String, Object> map = new HashMap<>();
        qw.allEq(map, false);
        return baseMapper.selectOne(qw);
    }

    @Override
    public String getSerialId(String serialName) {
        return getSerialId(serialName, null);
    }

    @Override
    public String getSerialId(String serialName, String pre) {
        DictSerial serial = getDictSerial(serialName);
        Long currentValue = serial.getCurrentValue();
        Integer length = serial.getSerialLength();
        if (currentValue == null && length == null) {
            log.error("生成主键失败！序列字典表DICT_SERIAL不存在名称为[{}]的记录。", serialName);
        }
        String id = (StringUtils.isBlank(pre) ? "" : pre) + String.format("%0" + length + "d", currentValue);
        return id;
    }

    public DictSerial getDictSerial(String serialName) {
        synchronized (this) {
            while (true) {
                Connection connect = null;
                Statement stmt = null;
                DictSerial serial = new DictSerial();
                try {
                    connect = dataSource.getConnection();
                    connect.setAutoCommit(false);
                    stmt = connect.createStatement();
                    stmt.addBatch("lock table dict_serial in exclusive mode");
                    stmt.executeBatch();
                    stmt.executeUpdate("update dict_serial set current_value=current_value+1 where serial_name='" + serialName + "'");
                    ResultSet resultSet = stmt.executeQuery("select serial_name serialName, current_value currentValue, serial_length serialLength from dict_serial where serial_name='" + serialName + "' ");
                    if (resultSet != null && resultSet.next()) {
                        serial.setSerialName(resultSet.getString("serialName"));
                        serial.setCurrentValue(resultSet.getLong("currentValue"));
                        serial.setSerialLength(resultSet.getInt("serialLength"));
                    }
                    connect.commit();
                    return serial;
                } catch (SQLException e2) {
                    log.error(e2.getMessage(), e2);
                    if (connect != null) {
                        try {
                            connect.rollback();
                        } catch (SQLException e1) {
                            log.error(e1.getMessage(), e1);
                        }
                    }
                    try {
                        if (stmt != null) {
                            stmt.close();
                        }
                        if (connect == null) {
                            continue;
                        }
                        connect.close();
                    } catch (Exception e3) {
                        log.error(e3.getMessage(), e3);
                    }
                } finally {
                    try {
                        if (stmt != null) {
                            stmt.close();
                        }
                        if (connect != null) {
                            connect.close();
                        }
                    } catch (Exception e4) {
                        log.error(e4.getMessage(), e4);
                    }
                }
            }
        }
    }
}
